package br.com.rookgraph.gui;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

import br.com.rookgraph.run.ArenaAlgoritmos;
import br.com.rookgraph.utils.ControleExecucao;
import br.com.rookgraph.utils.EnumGeracaoArvore;
import br.com.rookgraph.utils.ExecuteHeuristicas;
import javax.swing.JCheckBox;

public class JanelaDeDuelo extends JFrame {

	private static final long serialVersionUID = -2084449042096087006L;
	
	private JPanel contentPane;
	private JComboBox<?> selectAlgoritmo1;
	private JComboBox<?> selectAlgoritmo2;
	private JComboBox<?> selectArvore1;
	private JComboBox<?> selectArvore2;
	private JComboBox<?> selectControleExecucao;
	private JCheckBox chckbxHam1;
	private JSpinner numIteracoes;
	private JSpinner numV;
	private JSpinner dens;
	private static JTextArea console;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					JanelaDeDuelo frame = new JanelaDeDuelo();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 * @throws UnsupportedLookAndFeelException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public JanelaDeDuelo() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
//		UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		
		setResizable(false);
		setTitle("Duelo de algoritmos");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 514, 563);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JSeparator separator = new JSeparator();
		separator.setBounds(10, 232, 493, 2);
		contentPane.add(separator);
		
		console = new JTextArea();
		console.setEditable(false);
		console.setBounds(10, 245, 421, 184);
		contentPane.add(console);
		
		JScrollPane scrollPane = new JScrollPane(console, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setBounds(10, 245, 469, 279);
		
		contentPane.add(scrollPane);
		
		criarBotaoExecutar();
		
		criarBotaoFechar();
		
		criarSeparators();

		criarSpinners();

		criarLabels();

		criarComboBoxes();
	}

	private void criarBotaoExecutar() {
		JButton btnExecutar = new JButton("Executar");
		btnExecutar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				new Worker().execute();
			}

		});
		
		btnExecutar.setBounds(139, 198, 89, 23);
		contentPane.add(btnExecutar);
	}

	private void criarSeparators() {
		JSeparator separator = new JSeparator();
	
		separator.setBounds(10, 99, 493, 2);
		contentPane.add(separator);
	}

	private void criarBotaoFechar() {
		JButton btnFechar = new JButton("Fechar");
		btnFechar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
		
		btnFechar.setBounds(238, 198, 89, 23);
		contentPane.add(btnFechar);
	}

	private void criarSpinners() {
		numIteracoes = new JSpinner();
		numIteracoes.setModel(new SpinnerNumberModel(new Integer(500), null, null, new Integer(10)));
		numIteracoes.setBounds(109, 167, 78, 20);
		contentPane.add(numIteracoes);
		
		dens = new JSpinner();
		dens.setModel(new SpinnerNumberModel(10, 1, 100, 1));
		dens.setBounds(330, 161, 60, 20);
		contentPane.add(dens);
		
		numV = new JSpinner();
		numV.setModel(new SpinnerNumberModel(10, 1, 100000, 1));
		numV.setBounds(330, 136, 60, 20);
		contentPane.add(numV);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void criarComboBoxes() {
		selectControleExecucao = new JComboBox();
		selectControleExecucao.setModel(new DefaultComboBoxModel(ControleExecucao.values()));
		selectControleExecucao.setBounds(109, 136, 111, 20);
		contentPane.add(selectControleExecucao);
		
		selectAlgoritmo1 = new JComboBox();
		selectAlgoritmo1.setBounds(100, 42, 115, 20);
		selectAlgoritmo1.setModel(new DefaultComboBoxModel(ExecuteHeuristicas.values()));
		contentPane.add(selectAlgoritmo1);
		
		selectAlgoritmo2 = new JComboBox();
		selectAlgoritmo2.setBounds(100, 73, 115, 20);
		selectAlgoritmo2.setModel(new DefaultComboBoxModel(ExecuteHeuristicas.values()));
		contentPane.add(selectAlgoritmo2);
		
		selectArvore1 = new JComboBox();
		selectArvore1.setModel(new DefaultComboBoxModel(EnumGeracaoArvore.values()));
		selectArvore1.setBounds(295, 42, 137, 20);
		contentPane.add(selectArvore1);
		
		selectArvore2 = new JComboBox();
		selectArvore2.setModel(new DefaultComboBoxModel(EnumGeracaoArvore.values()));
		selectArvore2.setBounds(295, 73, 137, 20);
		contentPane.add(selectArvore2);
		
		chckbxHam1 = new JCheckBox("Ham");
		chckbxHam1.setBounds(407, 135, 72, 23);
		contentPane.add(chckbxHam1);
		
	}

	private void criarLabels() {
		Font fonte = new Font("Tahoma", Font.BOLD, 11);
		
		adicionarLabel("Algoritmo 1", SwingConstants.LEFT, 10, 42, 80, 20);
		adicionarLabel("Algoritmo 2", SwingConstants.LEFT, 10, 73, 80, 20);
		adicionarLabel("Critério de parada", SwingConstants.LEFT, 10, 136, 89, 14);
		adicionarLabel("Num. Iterações", SwingConstants.RIGHT, 10, 170, 89, 14);
		adicionarLabel("Configuração da execução", SwingConstants.RIGHT, 10, 105, 152, 20).setFont(fonte);
		adicionarLabel("Algoritmos", SwingConstants.RIGHT, 10, 11, 152, 20).setFont(fonte);
		adicionarLabel("Árvore 1", SwingConstants.RIGHT, 235, 45, 49, 14);
		adicionarLabel("Árvore 2", SwingConstants.RIGHT, 235, 74, 49, 14);
		adicionarLabel("Árvores iniciais", SwingConstants.RIGHT, 215, 11, 152, 20).setFont(fonte);
		adicionarLabel("Grafos gerados", SwingConstants.RIGHT, 242, 105, 111, 20).setFont(fonte);
		adicionarLabel("Num. Vértices", SwingConstants.RIGHT, 252, 139, 68, 14);
		adicionarLabel("Densidade", SwingConstants.RIGHT, 252, 164, 68, 14);
	}
	
	public JLabel adicionarLabel(String nomeLabel, int align, int b1, int b2, int b3, int b4) {
		JLabel label = new JLabel(nomeLabel);
		label.setHorizontalAlignment(align);
		label.setBounds(b1, b2, b3, b4);
		contentPane.add(label);
		
		return label;
	}

	public static void limpar() {
		console.setText("");
	}
	
	public static void logar(String texto) {
		console.append(texto + "\n");
		console.setCaretPosition(console.getText().length());
	}

	public static void logarMesmaLinha(String texto) {
		console.append(texto);
		console.setCaretPosition(console.getText().length());
	}
	
	public class Worker extends SwingWorker<String, String> {
	    @Override
	    protected String doInBackground() throws Exception {
	    	try {
	    		ExecuteHeuristicas alg1 = (ExecuteHeuristicas) selectAlgoritmo1.getSelectedItem();
				ExecuteHeuristicas alg2 = (ExecuteHeuristicas) selectAlgoritmo2.getSelectedItem();
				
				ControleExecucao cont = ((ControleExecucao) selectControleExecucao.getSelectedItem());
				cont = ControleExecucao.clonar(cont);
				cont.setQtdMaximaIteracoes((Integer) numIteracoes.getValue());
				
				EnumGeracaoArvore arvore1 = (EnumGeracaoArvore) selectArvore1.getSelectedItem();
				EnumGeracaoArvore arvore2 = (EnumGeracaoArvore) selectArvore2.getSelectedItem();
				ArenaAlgoritmos arena = new ArenaAlgoritmos(alg1, alg2, arvore1, arvore2, chckbxHam1.isSelected());
				
				int v = (Integer) numV.getValue();
				int d = (Integer) dens.getValue();
				
				arena.executarDuelo(cont, v, d);
	    	} catch (Exception e) {
	    		e.printStackTrace();
	    	}
	    	
	        return null;
	    }
	    
	    
	}
}
